#!/usr/bin/env python
#_*_coding:utf-8_*_
__author__ = 'apple'

import sys
reload(sys)

import os
import paramiko
import dbs

class SSH(object):
    def __init__(self):
        super(SSH, self).__init__()
        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    ## 执行命令
    def execute(self, command, host_info):
        try:
            self.ssh_connect(host_info=host_info)
            stdin, stdout, stderr = self.client.exec_command(command)
            err = stderr.read()
            if not err:
                content = stdout.read()
                result = {
                    'code': 0,
                    'message': 'success',
                    'data': content
                }
                return result
            result= {
                'code': 500,
                'message': err
            }
            return result
        except Exception as e:
            result = {
                'code': 520,
                'message': str(e)
            }
            return result

    ## 批量执行命令
    def mult_execute(self, command):
        result = {}
        data = self.get_hosts()
        if data.get('code') != 0:
            return data
        hosts_info = data['hosts']
        for host_info in hosts_info:
            data = self.execute(command, host_info)
            result[host_info[0]] = data
        return result

    ## 上传文件
    def upload(self, lpath, rpath, host_info):
        '''
        args:
            lpath : 本地要上传的文件绝对路径
            rpath : 远程的文件绝对路径
            host_info : 传入主机的执行信息
        '''
        try:
            self.ssh_connect(host_info)
            sftp = self.client.open_sftp()
            try:
                sftp.put(lpath, rpath)
                return {'code' : 0, 'message' : 'upload success'}
            except Exception as e: #sftp的异常
                return {'code' : 521, 'message' : str(e)}
        except Exception as e: #SSH连接的异常
            return {'code' : 520, 'message' : str(e)}

    ## 下载文件
    def download(self, rpath, lpath, host_info):
        try:
            self.ssh_connect(host_info)
            sftp = self.client.open_sftp()
            try:
                sftp.get(rpath, lpath)
                return {'code' : 0, 'message' : 'download success'}
            except Exception as e:
                return {'code' : 521, 'message' : str(e)}
        except Exception as e:
            return {'code' : 520, 'message' : str(e)}

    ## 批量上传文件
    def mult_upload(self, lpath, rpath):
        result = {}
        data = self.get_hosts()
        if data.get('code') != 0:
            return data
        hosts_info = data['hosts']
        for host_info in hosts_info:
            data = self.upload(rpath=rpath, lpath=lpath, host_info=host_info)
            result[host_info[0]] = data  # 主机=主机执行命令结果
        return result

    ## 批量下载
    def mult_download(self, rpath, lpath):
        result = {}
        data = self.get_hosts()
        if data.get('code') != 0:
            return data
        hosts_info = data['hosts']
        for host_info in hosts_info:
            hostname = host_info[0]
            # 处理文件名
            dir,filename = os.path.split(lpath)
            filename = '{hostname}-{filename}'.format(hostname=hostname, filename=filename)
            xlpath = os.path.join(dir, filename) # 这是新的本地路径
            data = self.download(lpath=xlpath, rpath=rpath, host_info=host_info)
            result[hostname] = data  #主机=主机执行命令结果
        return result


    ## 获取主机信息
    def get_hosts(self, host=False):
        try:
            conn, cur = dbs.db_connect()
            if host:
                query = '''
                SELECT 
                      ip,port,username,password 
                FROM 
                      cmdb_hosts
                WHERE ip = '{host}' '''.format(host=host)
            else:
                query = '''
                SELECT ip,port,username,password FROM cmdb_hosts'''
            cur.execute(query)
            if host:
                host = cur.fetchone()
                return {'code' : 0, 'message' : 'success' ,'host':host}
            hosts = cur.fetchall()
            return {'code' : 0 , 'message':'success', 'hosts' : hosts}
        except Exception as e:
            return {'code' : 522 ,'message': str(e) }

    def ssh_connect(self, host_info):
        # 把数据库查询格式转换成字典传参格式
        key = ('hostname', 'port', 'username', 'password')
        host_info = dict(zip(key,host_info))
        host_info['timeout'] = 3
        self.client.connect(**host_info)

    def view_hosts(self):
        conn ,cur = dbs.db_connect()
        query = 'SELECT hostname FROM cmdb_hosts'
        cur.execute(query)
        data = cur.fetchall()
        hosts = [ hostname[0] for hostname in data ]
        return  hosts

def main():
    s = SSH()
    host_info = s.get_hosts(host='172.16.7.197')['host']
    result = s.execute('uptime', host_info=host_info)
    #result = s.mult_execute('uptime')
    print result
    s.view_hosts()


if __name__ == '__main__':
    main()


